#include "ddl.h"
#include "uart.h"
#include "gpio.h"
#include "sysctrl.h"
#include "led.h"
#include "uart_api.h"
#include "mock_key.h"
#include "QG_driver.h"

#include "stdbool.h"
#include "stdio.h"
#include "string.h"
#include <stdlib.h>

#include "CAT1.h"
#include "cJSON.h"
#include "myUtility.h"

#include <stdio.h>  // 必须包含，提供 sscanf()
#include <string.h> // 提供字符串处理函数如 strtok(), strstr()

#define UNKNOWN_RSSI 999  // 自定义未知信号的标识值

uint8_t CAT1_state_low_power = 0;	//0未进入低功耗，1已进入低功耗

char dataToSend[SEND_MAX_LEN];
uint8_t UT0_RX_COUNT_PRE;

extern uint8_t UT0_IDLE_FLAG;
extern uint8_t UT0_RX_COUNT;
extern unsigned char UT0_RX_BUF[UT0_RX_MAX_LEN];
extern unsigned char UT0_TX_BUF[UT0_TX_MAX_LEN];
extern uint16_t UT0_RX_STA;   						//接收数据状态

volatile char device_imei[16] = {0};   // IMEI固定15字符，这里加上了结束符

uint8_t wakeup_from_RI = 0; //RI中断唤醒标志

_Bool NT26K_WaitRecive(void);
unsigned int sendCommand(char *Command, char *Response, unsigned long Timeout, unsigned char Retry);
void log_errAndReset(uint8_t num);

void CAT1_PWRKEY_init()
{
	
	stc_gpio_cfg_t stcGpioCfg;
    
    	///< 打开GPIO外设时钟门控
    	Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
	
	///< 端口方向配置->输出(其它参数与以上（输入）配置参数一致)
    	stcGpioCfg.enDir = GpioDirOut;
    	///< 端口上下拉配置->
    	stcGpioCfg.enPu = GpioPuEnable;
    	stcGpioCfg.enPd = GpioPdDisable;
	stcGpioCfg.enDrv = GpioDrvL;
//    stcGpioCfg.enOD = GpioOdEnable;
    	///< PWRKEY关闭
    	Gpio_ClrIO(PWRKEY_PORT, PWRKEY_PIN);
    
    	///< GPIO IO LED端口初始化
    	Gpio_Init(PWRKEY_PORT, PWRKEY_PIN, &stcGpioCfg);
}

void CAT1_TPS_init()
{
	stc_gpio_cfg_t stcGpioCfg;
    
    	///< 打开GPIO外设时钟门控
    	Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
	
	///< 端口方向配置->输出(其它参数与以上（输入）配置参数一致)
    	stcGpioCfg.enDir = GpioDirOut;
    	///< 端口上下拉配置->
    	stcGpioCfg.enPu = GpioPuEnable;
    	stcGpioCfg.enPd = GpioPdDisable;
	stcGpioCfg.enDrv = GpioDrvL;
//    stcGpioCfg.enOD = GpioOdEnable;
    	///< 通电打开
    	Gpio_ClrIO(TPS_EN_PORT, TPS_EN_PIN);
    
    	///< GPIO IO 端口初始化
    	Gpio_Init(TPS_EN_PORT, TPS_EN_PIN, &stcGpioCfg);
}

void CAT1_MAIN_DTR_init()
{
	stc_gpio_cfg_t stcGpioCfg;
    
	///< 打开GPIO外设时钟门控
	Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
		
		///< 端口方向配置->输出(其它参数与以上（输入）配置参数一致)
	stcGpioCfg.enDir = GpioDirOut;
	///< 端口上下拉配置->
	stcGpioCfg.enPu = GpioPuEnable;
	stcGpioCfg.enPd = GpioPdDisable;
	stcGpioCfg.enDrv = GpioDrvL;
	//    stcGpioCfg.enOD = GpioOdEnable;
	///< 默认DTR状态，三极管不导通
	Gpio_ClrIO(MAIN_DTR_PORT, MAIN_DTR_PIN);

	///< GPIO IO 端口初始化
	Gpio_Init(MAIN_DTR_PORT, MAIN_DTR_PIN, &stcGpioCfg);
}

void CAT1_RESET_init()
{
	stc_gpio_cfg_t stcGpioCfg;
    
	///< 打开GPIO外设时钟门控
	Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
		
		///< 端口方向配置->输出(其它参数与以上（输入）配置参数一致)
	stcGpioCfg.enDir = GpioDirOut;
	///< 端口上下拉配置->
	stcGpioCfg.enPu = GpioPuEnable;
	stcGpioCfg.enPd = GpioPdDisable;
	stcGpioCfg.enDrv = GpioDrvL;
	//    stcGpioCfg.enOD = GpioOdEnable;
	///< 默认DTR状态，三极管不导通
	Gpio_ClrIO(RESET_PORT, RESET_PIN);

	///< GPIO IO 端口初始化
	Gpio_Init(RESET_PORT, RESET_PIN, &stcGpioCfg);
}

void CAT1_RESET_set(uint8_t state)
{
	if(state == ON)
	{
		Gpio_ClrIO(RESET_PORT, RESET_PIN); //拉高
	}
	if(state == OFF)
	{
		Gpio_SetIO(RESET_PORT, RESET_PIN); //拉低复位
	}
}

//MAIN_RI中断函数在QG_driver.c中
//MAIN_RI引脚初始化，该引脚用于CAT1模组的主动唤醒
void CAT1_MAIN_RI_init()
{
	stc_gpio_cfg_t stcGpioCfg;
    
	///< 打开GPIO外设时钟门控
	Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
		
	///< 端口方向配置->输出(其它参数与以上（输入）配置参数一致)
	stcGpioCfg.enDir = GpioDirIn;
	///< 端口上下拉配置->
	stcGpioCfg.enPu = GpioPuEnable;
	stcGpioCfg.enPd = GpioPdDisable;
	stcGpioCfg.enOD = GpioOdDisable;

	///< GPIO IO 端口初始化
	Gpio_Init(MAIN_RI_PORT, MAIN_RI_PIN, &stcGpioCfg);

	Gpio_EnableIrq(MAIN_RI_PORT, MAIN_RI_PIN, GpioIrqRising);
	Gpio_EnableIrq(MAIN_RI_PORT, MAIN_RI_PIN, GpioIrqFalling);
	EnableNvic(PORTB_IRQn, IrqLevel3, TRUE); //开启外部中断向量

}

void CAT1_TPS_set(uint8_t state)
{
	if(state == ON)
	{
		Gpio_ClrIO(TPS_EN_PORT, TPS_EN_PIN);
	}
	if(state == OFF)
	{
		Gpio_SetIO(TPS_EN_PORT, TPS_EN_PIN);
	}
}
/**
 * ON MAIN_DTR拉高，OFF MAIN_DTR拉低
 */
void CAT1_MAIN_DTR_set(uint8_t state)
{
	if(state == ON)
	{
		Gpio_ClrIO(MAIN_DTR_PORT, MAIN_DTR_PIN);
	}
	if(state == OFF)
	{
		Gpio_SetIO(MAIN_DTR_PORT, MAIN_DTR_PIN);
	}
}
/**
 * 让CAT1模组进入睡眠模式
 */
void CAT1_enterLowPowerMode(boolean_t isEnter)
{
	if (isEnter)
	{
	
		uint8_t i = 0;
		CAT1_MAIN_DTR_set(ON);		//拉高MAIN_DTR

		while (1)
		{
			if(sendCommand("AT+QSCLK=1", "OK", 10, 2))
			{
				Debug_Printf("\r\nCAT1 low power mode...\r\n");
			}else
			{
				Debug_Printf("\r\nCAT1 low power mode fail...\r\n");
				if (i++ > 2)
				{
					log_errAndReset(6);
				}
			}	
		}
	}else if (isEnter == FALSE)
	{
		CAT1_MAIN_DTR_set(OFF);		//拉低MAIN_DTR来唤醒CAT1模组
		Debug_Printf("\r\nCAT1 wake up...\r\n");
	}
		
}

/**
 * 函数接收一个 uint8_t 类型的参数 num，根据其值输出对应的错误信息到调试打印，
 * 并调用 NVIC_SystemReset 执行系统复位操作。该函数包含一个无限循环，确保在复位前不会继续执行其他代码。
 */
void log_errAndReset(uint8_t num)
{
	switch (num)
	{
		case 1:
			Debug_Printf("\r\nSIM is Abnormal\r\n");
			break;
		case 2:
			Debug_Printf("\r\nThe network was not successfully registered\r\n");
			break;
		case 3:
			Debug_Printf("\r\nThe TCP/IP configured was fail\r\n");
			break;
		case 4:
			Debug_Printf("\r\nThe TCP/IP env was fail \r\n");
			break;
		case 5:
			Debug_Printf("\r\n Open connect err \r\n");
			break;
		case 6:
			Debug_Printf("\r\nenter low power mode fail\r\n");
			break;
		case 7:
			Debug_Printf("\r\nCAT1 default configure fail\r\n");	//RI配置失败
		default:
			Debug_Printf("\r\nUnknown cause\r\n");
			break;
	}
	NVIC_SystemReset();
	// SCB->AIRCR  = 0X05FA0004; 
	while(1)
	{
		
	}
}

/*
	检测Module与串口是否连通，能否接收AT命令： AT
	查看SIM卡是否到位： AT+CPIN?
	测试信号： AT+CSQ
	查看运营商： AT+COPS?
	获取模块标识： AT+CGMM
	获取模块厂商标识： AT+CGMI
	查看SIM卡是否到位： AT+CPIN?
	网络注册。获得手机的注册状态： AT+CREG?
*/
void NT26K_selfTest(void)
{
	if (sendCommand("AT+CPIN?\r\n", "READY", 10, 2))
	{
		Debug_Printf("\r\nSIM is correct...\r\n");
	}else log_errAndReset(1);
	if (sendCommand("AT+CREG?\r\n", "OK", 10, 2))
	{
		Debug_Printf("\r\nThe NET registered suc...\r\n");
	}else log_errAndReset(2);
	if (sendCommand("AT+QICSGP=1,1,\"MOBILE\",\"\",\"\",1\r\n", "OK", 10, 2))
	{
		Debug_Printf("\r\nThe TCP/IP configured suc...\r\n");
	}else log_errAndReset(3);
	if (sendCommand("AT+QIACT=1\r\n", "OK", 10, 2))
	{
		Debug_Printf("\r\nThe TCP/IP environment was activated...\r\n");
	}else log_errAndReset(4);
	
}
/**
 * 配置RI引脚在MQTT消息到来时触发振铃
 */
void NT26K_ConfigureDefault(void)
{
	uint8_t flag = 0;
	if (sendCommand("AT+QURCCFG=\"urcport\", \"uart1\"\r\n", "OK", 10, 2))
	{
		/* code */
	}else flag = 1;
	if (sendCommand("AT+QURCCFG=\"urcport\"\r\n", "OK", 10, 2))
	{
		/* code */
	}else flag = 1;
	if (sendCommand("AT+QCFG=\"urc/ri/other\",\"pulse\"\r\n", "OK", 10, 2))
	{
		/* code */
	}else flag = 1;
	if (sendCommand("AT+QCFG=\"risignaltype\",\"physical\"\r\n", "OK", 10, 2))
	{
		/* code */
	}else flag = 1;
	if (flag == 1)
	{
		log_errAndReset(7);		//配置失败，重启
	}
	

}

/**
 * Command  发送指令
 * Response 期望响应
 * Timeout 超时等待时间 单位10ms
 * Retry   重试次数
 * 用于发送指令并等待期望的响应。
 * 它接受指令字符串、期望的响应字符串、超时时间（单位为10毫秒）以及重试次数作为参数，并通过串口发送指令，
 * 若在超时时间内接收到匹配的响应则返回1，否则返回0。
**/
unsigned int sendCommand(char *Command, char *Response, unsigned long Timeout, unsigned char Retry)
{
	unsigned char n;
	UT0_RX_Clr();
	for (n = 0; n < Retry; n++)
	{
		Uart_SendString(M0P_UART0, Command);

		Debug_Printf("\r\n***************send command****************\r\n");
		Debug_Printf((char*)Command);
		
		uint16_t Time_Cont = 0;
		while (Timeout > 0)
		{
			Timeout--;
			Debug_Printf("\r\ntiming retain: %d\r\n", Timeout);
			
			if(NT26K_WaitRecive() == REV_OK)
			{
				if (strstr((char*)UT0_RX_BUF, (char*)Response) != NULL)
				{				
					Debug_Printf("\r\n***************receive****************\r\n");
					Debug_Printf((char*)UT0_RX_BUF);
					UT0_RX_Clr();
					return 1;
				}
			}
			delay1ms(10);
		}
		Debug_Printf("\r\n***************receive****************\r\n");
		Debug_Printf((char*)UT0_RX_BUF);
	}
	Debug_Printf("\r\n***************receive****************\r\n");
	Debug_Printf((char*)UT0_RX_BUF);
	UT0_RX_Clr();
	return 0;
}

/**
 * Command  发送指令
 * Response 期望响应
 * resultResp 返回响应内容
 * Timeout 超时等待时间 单位10ms
 * Retry   重试次数
 * 用于发送指令并等待期望的响应。
 * 它接受指令字符串、期望的响应字符串、超时时间（单位为10毫秒）以及重试次数作为参数，并通过串口发送指令，
 * 若在超时时间内接收到匹配的响应则返回1，否则返回0。
**/
unsigned int sendCommandDetail(char *Command, char *Response, char *resultResp, unsigned long Timeout, unsigned char Retry)
{
	unsigned char n;
	UT0_RX_Clr();
	for (n = 0; n < Retry; n++)
	{
		Uart_SendString(M0P_UART0, Command);

		Debug_Printf("\r\n***************send command****************\r\n");
		Debug_Printf((char*)Command);
		
		uint16_t Time_Cont = 0;
		while (Timeout > 0)
		{
			Timeout--;
			Debug_Printf("\r\ntiming retain: %d\r\n", Timeout);
			
			if(NT26K_WaitRecive() == REV_OK)
			{
				if (strstr((char*)UT0_RX_BUF, (char*)Response) != NULL)
				{				
					Debug_Printf("\r\n***************receive****************\r\n");
					Debug_Printf((char*)UT0_RX_BUF);
					memcpy(resultResp, UT0_RX_BUF, strlen((char*)UT0_RX_BUF));

					UT0_RX_Clr();
					return 1;
				}
			}
			delay1ms(10);
		}
		Debug_Printf("\r\n***************receive****************\r\n");
		Debug_Printf((char*)UT0_RX_BUF);
	}
	Debug_Printf("\r\n***************receive****************\r\n");
	Debug_Printf((char*)UT0_RX_BUF);
	UT0_RX_Clr();
	return 0;
}

uint8_t CAT1_PWRKEY_set(uint8_t state)
{
	if(state == ON)
	{
		//PWRKEY接地500ms以上开机
		Gpio_SetIO(PWRKEY_PORT, PWRKEY_PIN);
		delay1ms(520);
		Gpio_ClrIO(PWRKEY_PORT, PWRKEY_PIN);
		//判断是否开启
		delay1ms(2000);//等待开机
		Uart_SendString(M0P_UART0, "AT\r\n");
		if (sendCommand("AT\r\n", "OK", 10, 2) == 1)
		{
			Debug_Printf("\r\npower open suc\r\n");
			return 1;
		}else 
		{
			Debug_Printf("\r\npower open err, restart...\r\n");
			
			Gpio_ClrIO(APP_LED_PORT, APP_LED_PIN);
			Gpio_ClrIO(GpioPortA, GpioPin11);
			// soft_reset();
			// while(1)
			// {
			// }
			return 0;
		}
	}
	else if(state == OFF)
	{
		//PWRKEY接地650ms以上关机
		Gpio_ClrIO(PWRKEY_PORT, PWRKEY_PIN);
		delay1ms(670);
		Gpio_SetIO(PWRKEY_PORT, PWRKEY_PIN);
		return 1;
	}
	return 0;
}
/**
 * AT+IPR=115200
	OK
 */
uint8_t setBaudRate(uint32_t baudRate)
{
	char cmdBuf[32];
	uint8_t len = 0;
	
	//设置波特率
	memset(cmdBuf, 0, sizeof(cmdBuf));
	len = snprintf(cmdBuf, sizeof(cmdBuf), "AT+IPR=%d\r\n", baudRate);
	Debug_Printf("\r\nsendData: %s", cmdBuf);
	if (sendCommand(cmdBuf, "OK", 100, 2) == 1)
	{
		uart0_init(9600);
		if (sendCommand(cmdBuf, "OK", 100, 2) == 1)
		{
			Debug_Printf("\r\nset baud rate suc\r\n");
			return 1;
		}else return 0;
	}
	else
	{
		Debug_Printf("\r\nset baud rate err\r\n");
		return 0;
	}
	
}


/**
 * 连接云平台
 * 返回  1 成功     0 失败
 */
uint8_t NT26K_Connect_MQTT(void)
{
	uint8_t len = 0;
	memset(dataToSend, 0, SEND_MAX_LEN);
	len = snprintf(dataToSend, SEND_MAX_LEN, "AT+QMTOPEN=%d,%s,%d\r\n", 
				CLIENT_IDX, OPENADDRESS, OPENPORT);
	Debug_Printf("\r\nsendData: %s", dataToSend);
	while (!sendCommand(dataToSend, "OK", 100, 2))
	{
		Debug_Printf("\r\nconn open err");
		return 0;
	}

	memset(dataToSend, 0, SEND_MAX_LEN);
	len = snprintf(dataToSend, SEND_MAX_LEN, "AT+QMTCONN=%d,%s,%s,%s\r\n", 
				CLIENT_IDX, DEVICE_ID, USERNAME, PASSWORD);
	Debug_Printf("\r\nsendData: %s", dataToSend);
	while (!sendCommand(dataToSend, "OK", 100, 3))
	{
		Debug_Printf("\r\nconn err");
		log_errAndReset(5);
		return 0;
	}

	return 1;
}



/**
 * 订阅主题
 * 返回   1 成功      0失败
 */
uint8_t NT26K_Subscribe(void)
{
	uint8_t len = 0;
	memset(dataToSend, 0, SEND_MAX_LEN);
	len = snprintf(dataToSend, SEND_MAX_LEN, "AT+QMTSUB=%d,%d,\"%s\",%d\r\n", CLIENT_IDX, MSGID, "set_data_flag", QOS);
	Debug_Printf("\r\nsendData: %s", dataToSend);
	while (!sendCommand(dataToSend, "OK", 100, 2))
	{
		Debug_Printf("\r\nsub err");
		return 0;
	}
	return 1;
}

//==========================================================
//	函数名称：	NT26K_WaitRecive
//
//	函数功能：	等待接收完成
//
//	入口参数：	无
//
//	返回参数：	REV_OK-接收完成		REV_WAIT-接收超时未完成
//
//	说明：		循环调用检测是否接收完成
//==========================================================
_Bool NT26K_WaitRecive(void)
{

	if(UT0_RX_COUNT == 0) 							//如果接收计数为0 则说明没有处于接收数据中，所以直接跳出，结束函数
		return REV_WAIT;
		
	if(UT0_RX_COUNT == UT0_RX_COUNT_PRE)				//如果上一次的值和这次相同，则说明接收完毕
	{
		UT0_RX_COUNT = 0;							//清0接收计数
			
		return REV_OK;								//返回接收完成标志
	}
		
	UT0_RX_COUNT_PRE = UT0_RX_COUNT;					//置为相同
	
	return REV_WAIT;								//返回接收未完成标志

}

//==========================================================
//	函数名称：	NT26K_GetData
//
//	函数功能：	获取平台返回的数据
//
//	入口参数：	等待的时间(乘以10ms)
//
//	返回参数：	平台返回的原始数据
//
//	说明：		不同网络设备返回的格式不同，需要去调试
//				如ESP8266的返回格式为	"+IPD,x:yyy"	x代表数据长度，yyy是数据内容
//==========================================================
unsigned char* NT26K_GetData(unsigned short timeOut)
{

	char *ptrQMTRECV = NULL;
	
	do
	{
		timeOut--;
		if(NT26K_WaitRecive() == REV_OK)						//如果接收完成
		{
			ptrQMTRECV = strstr((char *)UT0_RX_BUF, "QMTRECV");		//搜索“QMTRECV”头
			if(ptrQMTRECV == NULL)							//如果没找到，可能是QMTRECV头的延迟，还是需要等待一会，但不会超过设定的时间
			{
				// Uart_SendString(M0P_UART1, "\"QMTRECV\" not found\r\n");
			}
			else
			{
				// Debug_Printf("\r\ndataPtr found\r\n");
				ptrQMTRECV = strchr(ptrQMTRECV, ':');				//找到':'
				if(ptrQMTRECV != NULL)
				{
					ptrQMTRECV++;
					return (unsigned char *)(ptrQMTRECV);
				}
				else
					return NULL;
			}
		}
		// Debug_Printf("\r\ntimeout:%d\r\n", timeOut);
		delay1ms(10);												//延时等待
	} while(timeOut > 0);
	
	return NULL;													//超时还未找到，返回空指针

}

/**
 * topic 	发送数据的目标主题
 * buf	要发送的数据
 */
uint8_t NT26K_SendData(char* topic, char* buf)
{
	char cmdBuf[64];
	
	UT0_RX_Clr();								//清空接收缓存
	snprintf(cmdBuf, 64, "AT+QMTPUBEX=%d,%d,%d,%d,\"%s\",%d\r\n"
					,CLIENT_IDX, MSGID, QOS, RETAIN, topic, strlen(buf));		//发送命令
	if(sendCommand(cmdBuf, ">", 10, 2))				//收到‘>’时可以发送数据
	{
		if (sendCommand(buf, "OK", 10, 2))		//发送要发送的数据
		{
			// Debug_Printf("\r\nNT26K sendData suc\r\n");
			return 1;							//如果发送成功，返回1
		}else
		{
			// Debug_Printf("\r\nNT26K sendData err\r\n");
			return 0;							//如果没有收到‘OK’，则发送失败
		}
		 
	}else return 0;					//如果没有收到‘>’，则发送失败
}

void Resolve_Rev(unsigned char *data)
{
	//+QMTRECV: 0,1,"set_data_flag","{"taskId":14,"payload":{"swtich_power":false}}"
	char *req_payload = NULL;
	char *cmdid_topic = NULL;

	unsigned short topic_len = 0;
	unsigned short req_len = 0;
	
	unsigned char qos = 1;
	static unsigned short pkt_id = 0;
	
	unsigned char type = 0;
	
	short result = 0;

	char *dataPtr = NULL;
	char numBuf[10];
	int num = 0;

	// Debug_Printf("\r\nenter resolve\r\n");
	//使用cJson解析收到的数据
	cJSON *cJson_payload, *cJson_params, *cJson_key, *cJson_id;

	req_payload = strchr((char *)data, '{');
	cJson_payload =  cJSON_Parse(req_payload);
	cJson_id = cJSON_GetObjectItem(cJson_payload, "taskId");
	pkt_id = cJson_id->valueint;
	cJson_params = cJSON_GetObjectItem(cJson_payload, "payload");
	cJson_key =  cJSON_GetObjectItem(cJson_params, "switch_power");
	if (cJson_key != NULL)
	{
		// Debug_Printf("\r\ncjson type: %d\r\n", cJson_key->type);
		if (cJson_key->valueint == cJSON_True)
		{ 
			if (QG_getPowerState() == FALSE)
				power_set_blocking();		
		}
		else 
		{
			if (QG_getPowerState() == TRUE)
				power_set_blocking();
		}
	}
	cJson_key =  cJSON_GetObjectItem(cJson_params, "switch_sound");
	if (cJson_key != NULL)
	{
		// Debug_Printf("\r\ncjson type: %d\r\n", cJson_key->type);
		if (cJson_key->valueint == cJSON_True)
		{ 
			sound_set_blocking();
			// Debug_Printf("\r\nset sound ON\r\n");
		}
		else 
		{
			sound_set_blocking();
			// Debug_Printf("\r\nset sound OFF\r\n");
		}
	}
	cJson_key =  cJSON_GetObjectItem(cJson_params, "disperse_state");
	if (cJson_key != NULL)
	{
		// Debug_Printf("\r\ncjson type: %d\r\n", cJson_key->type);
		if (cJson_key->valueint == cJSON_True)
		{ 
			if (QG_getPowerState() == FALSE)
			{
				power_set_blocking();
			}
			QG_setDisperseState(ON);
			// memset(dataToSend, 0, SEND_MAX_LEN);
			// uint8_t len = snprintf(dataToSend, SEND_MAX_LEN, 
               //  "{\"disperse_state\":%d}", QG_info.state);
            	// NT26K_SendData("warning_flag", dataToSend);
			// Debug_Printf("\r\nset disperse state ON\r\n");		
		}
		else 
		{
			if (QG_getPowerState() == TRUE)
			{
				power_set_blocking();
			}			
			// Debug_Printf("\r\nset disperse state OFF\r\n");
			QG_setDisperseState(OFF);
		}
	}
	// Debug_Printf("\r\ntopic:%s, taskid:%s, payload:%s", cmdid_topic, pkt_id, req_payload);
	//回复命令
	if(pkt_id != NULL)
	{
		char reply_buf[128];
		int len = 0;
		memset(dataToSend, 0, SEND_MAX_LEN);
		char* dataParamsJson = cJSON_PrintUnformatted(cJson_params);
		len = snprintf(reply_buf, sizeof(reply_buf), "{\"taskId\":%d,\"resultPayload\":%s}",
												pkt_id, dataParamsJson);
		// Debug_Printf("\r\nreply_buf:%s, dataParamsJson:%s, len:%d\r\n", reply_buf, dataParamsJson, len);

		//构建AT命令
		snprintf(dataToSend, SEND_MAX_LEN, "AT+QMTPUBEX=%d,%d,%d,%d,\"%s\",%d\r\n",
					CLIENT_IDX, MSGID, QOS, RETAIN, "set_result_flag", len);
       	// Debug_Printf("\r\nsendData: %s", dataToSend);
		if (sendCommand(dataToSend, ">", 10, 2))
		{
			if (sendCommand(reply_buf, "OK", 10, 2))
			{
				Debug_Printf("\r\nreply suc\r\n");
			}else Debug_Printf("\r\nreply err\r\n");
		}
		// {"taskId":16,"resultPayload":{"switch_power":false}}
		
		free(dataParamsJson);								
	}
	
	cJSON_Delete(cJson_payload);
}

/**
 * 判断是什么卡
 */
void identifyCarrier(char* code, char** name) {
    char prefix[7];
    // 提取前6位字符
    strncpy(prefix, code, 6);
    prefix[6] = '\0'; // 确保字符串结束

    // 中国移动判断
    if (strncmp(prefix, "898600", 6) == 0 || 
        strncmp(prefix, "898602", 6) == 0 || 
        strncmp(prefix, "898604", 6) == 0 || 
        strncmp(prefix, "898607", 6) == 0) {
        *name = "CMCC";
    }
    // 中国联通判断
    else if (strncmp(prefix, "898601", 6) == 0 || 
             strncmp(prefix, "898606", 6) == 0 || 
             strncmp(prefix, "898609", 6) == 0) {
        *name = "CUCC";
    }
    // 中国电信判断
    else if (strncmp(prefix, "898603", 6) == 0 || 
             strncmp(prefix, "898611", 6) == 0) {
        *name = "CTCC";
    }
    // 中国广电判断
    else if (strncmp(prefix, "898615", 6) == 0) {
        *name = "CBN";
    }
    // 未知运营商
    else {
        *name = "UNKNOWN";
    }
}

/**
 * 获取当前网络频段信息
 * @param band_info 存储频段信息的缓冲区 (最小50字节)
 * @return 1成功, 0失败
 */
uint8_t NT26K_getNetworkBand(char *band_info) {
    char resultResp[256];
    memset(resultResp, 0, sizeof(resultResp));
    
    // 发送AT命令
    if (!sendCommandDetail("AT+QNWINFO\r\n", "OK", resultResp, 10, 2)) {
        Debug_Printf("\r\n[ERR] AT+QNWINFO failed");
        return 0;
    }
    
    // 解析响应
    char *line = resultResp;
    char *saveptr = NULL;
    char *token = my_strtok_r(line, "\n", &saveptr);
    
    while (token != NULL) {
        // 查找包含频段信息的行
        if (strstr(token, "+QNWINFO:") != NULL) {
            // 示例: +QNWINFO: "FDD LTE",46001,"LTE BAND 3",1650
            
            // 提取频段字段
            char *field = token;
            char *field_save = NULL;
            int field_count = 0;
            
            // 分割逗号分隔的字段
            field = my_strtok_r(token, ",", &field_save);
            while (field != NULL) {
                field_count++;
                
                // 第三个字段是频段信息
                if (field_count == 3) {
                    // 清理字段: 去除空格和引号
                    char *clean = field;
                    while (*clean == ' ' || *clean == '"') clean++;
                    
                    // 去除尾部引号
                    char *end = clean + strlen(clean) - 1;
                    while (end > clean && (*end == '"' || *end == '\r')) end--;
                    *(end + 1) = '\0';
                    
                    // 复制到输出缓冲区
                    strncpy(band_info, clean, 50);
                    return 1;
                }
                
                field = my_strtok_r(NULL, ",", &field_save);
            }
        }
        token = my_strtok_r(NULL, "\n", &saveptr);
    }
    
    Debug_Printf("\r\n[ERR] Band info not found in response");
    return 0;
}
/**
 * 	AT+CGSN=1
	+CGSN: "864784074801055"

	OK
 * 
 * 	AT+QCCID
	+QCCID: 89861124201034627921

	OK
 * 获取并上传设备信息
 * 返回 1  成功   0 失败
 */
uint8_t NT26K_sendDeviceInfo(void)
{
    char resultResp[256];
    char device_imei[16] = {0};  // 固定大小缓冲区
    char device_iccid[24] = {0}; // ICCID最大22+1
    
    memset(dataToSend, 0, SEND_MAX_LEN);

    // ============== IMEI 采集 ==============
    memset(resultResp, 0, sizeof(resultResp));
    if (!sendCommandDetail("AT+CGSN=1\r\n", "OK", resultResp, 100, 2)) {
        Debug_Printf("\r\n[ERR] AT+CGSN=1 failed");
        return 0;
    }

    // 逐行搜索CGSN响应
    char *line = strtok(resultResp, "\n");
    while (line) {
        if (strstr(line, "+CGSN:")) {
            // 格式: +CGSN: "864784074801055"
            char *start = strchr(line, '\"');
            char *end = start ? strchr(start + 1, '\"') : NULL;
            
            if (start && end) {
                size_t len = end - start - 1;
                if (len > 15) len = 15;
                strncpy(device_imei, start + 1, len);
                device_imei[len] = '\0';
                break;
            }
        }
        line = strtok(NULL, "\n");
    }

    if (strlen(device_imei) != 15) {
        Debug_Printf("\r\n[ERR] Invalid IMEI: %s", device_imei);
        return 0;
    }

    // ============== ICCID 采集 ==============
    memset(resultResp, 0, sizeof(resultResp));
    if (!sendCommandDetail("AT+QCCID\r\n", "OK", resultResp, 100, 2)) {
        Debug_Printf("\r\n[ERR] AT+QCCID failed");
        return 0;
    }

    // 逐行搜索QCCID响应
    line = strtok(resultResp, "\n");
    while (line) {
        if (strstr(line, "+QCCID:")) {
            // 格式: +QCCID: 89861124201034627921
            char *colon = strchr(line, ':');
            if (colon) {
                // 跳过冒号和后续空格
                char *iccid_start = colon + 1;
                while (*iccid_start == ' ') iccid_start++;
                
                // 提取到行尾
                char *end = strpbrk(iccid_start, "\r\n");
                if (end) *end = '\0';
                
                strncpy(device_iccid, iccid_start, sizeof(device_iccid)-1);
                break;
            }
        }
        line = strtok(NULL, "\n");
    }

    // ============== 数据验证和上报 ==============
    if (strlen(device_iccid) < 19) { // ICCID通常19-20位
        Debug_Printf("\r\n[ERR] Invalid ICCID: %s", device_iccid);
        return 0;
    }

    int len = snprintf(dataToSend, SEND_MAX_LEN, 
        "{\"manufacturer_name\":\"lierda\","
        "\"software_version\":\"1.0\","
        "\"hardware_version\":\"1.0\","
        "\"IMEI\":\"%s\","
        "\"module_type\":\"NT26K\","
        "\"ICCID\":\"%s\","
        "\"terminal_type\":\"QG_001\"}",
        device_imei, device_iccid);

    return NT26K_SendData("info_report", dataToSend) ? 1 : 0;
}

//返回值转换成具体信号值
int rssi_to_dbm(int rssi) {
    // 处理特殊值
    if (rssi == 0) return -113;   // -113 dBm 及以下，返回最差可能值
    if (rssi == 1) return -111;   // -111 dBm
    if (rssi == 31) return -51;   // -51 dBm 及以上，返回最好可能值
    if (rssi == 99) return UNKNOWN_RSSI; // 未知或未检测到
    
    // 处理范围值 2-30
    if (rssi >= 2 && rssi <= 30) {
        // 标准转换公式：dBm = 2 * RSSI - 113
        return 2 * rssi - 113;
    }
    
    // 无效的RSSI输入
    return UNKNOWN_RSSI;
}
/**
 * 获取并上传信号数据
 * 上报主题为signal_report
 */
uint8_t NT26K_sendDeviceSignal(void)
{
	char resultResp[300];
	// char *revolseString = NULL;
    	int8_t rsrp = 99;  //信号强度
	int8_t sinr = -1;  //信噪比
	int16_t pci = 0;    //物理小区标识
	int8_t ecl = 0;    //E-UTRA载波频率
	int32_t cell_id = 0; //小区ID

	memset(resultResp, 0, sizeof(resultResp));
	memset(dataToSend, 0, SEND_MAX_LEN);

	/**
	 * 	AT+CSQ
		+CSQ:19,0
		OK
	 */
	// ============== 修复1：AT+CSQ 处理 ==============
    if (sendCommandDetail("AT+CSQ\r\n", "OK", resultResp, 5, 2)) {
        char *line = NULL;
        char *saveptr_line = NULL;  // 用于strtok_r的上下文保存
        line = my_strtok_r(resultResp, "\n", &saveptr_line);
        
        while (line != NULL) {
            if (strstr(line, "+CSQ:") != NULL) {
                char *ptr = strchr(line, ':');
                if (ptr && sscanf(ptr + 1, "%d,%d", &rsrp, &sinr) == 2) {
                    Debug_Printf("rsrp = %d, sinr = %d\n", rsrp, sinr);
                }
                break; // 找到后退出循环
            }
            line = my_strtok_r(NULL, "\n", &saveptr_line);
        }
    }
	/**
	 * 	AT+QCELL? 
		//获取服务小区和邻区信息。 
		+QCELL: "servingcell","LTE",460,00,550b,d6b5c0,123,36 
		+QCELL: "neighbourcell inter","LTE",460,00,550b,5e05e2a,20,12 
		+QCELL: "neighbourcell inter","LTE",460,00,550b,5c4ef29,121,25 
		+QCELL: "neighbourcell","GSM",460,00,550b,d89,35,
		+QCELL: "neighbourcell","GSM",460,00,550b,34b8,10,45 
		OK
	*/
	memset(resultResp, 0, sizeof(resultResp));
	// ============== 修复2：AT+QCELL? 处理 ==============
    	memset(resultResp, 0, sizeof(resultResp));
    	if (sendCommandDetail("AT+QCELL?\r\n", "OK", resultResp, 10, 2)) {
		char *line = NULL;
		char *saveptr_line = NULL;  // 外层分割上下文
		line = my_strtok_r(resultResp, "\n", &saveptr_line);

		while (line != NULL) {
			if (strstr(line, "servingcell") && strstr(line, "+QCELL:")) {
				char *field = line;
				char *saveptr_field = NULL;  // 内层分割上下文
				int field_count = 0;
				char *hex_field = NULL;
				char *pci_field = NULL;

				// 安全的内层字段分割
				field = my_strtok_r(line, ",", &saveptr_field);
				while (field != NULL) {
					// 清理字段中的引号和空格
					char *clean_field = field;
					while (*clean_field == ' ' || *clean_field == '\"') clean_field++;
					
					if (field_count == 5) hex_field = clean_field;   // 第6字段: Cell ID
					else if (field_count == 6) pci_field = clean_field; // 第7字段: PCI
					
					field = my_strtok_r(NULL, ",", &saveptr_field);
					field_count++;
				}

				if (hex_field && pci_field) {
					cell_id = (uint32_t)strtoul(hex_field, NULL, 16);
					pci = (uint16_t)atoi(pci_field);
					Debug_Printf("cell_id: %x, pci: %d", cell_id, pci);
					break; // 成功解析后退出
				}
			}
			line = my_strtok_r(NULL, "\n", &saveptr_line); // 安全获取下一行
        	}
    	}
	int len = snprintf(dataToSend, SEND_MAX_LEN, \
			"{\"rsrp\":\"%d\"," \
			"\"sinr\":\"0\"," \
			"\"pci\":\"%d\"," \
			"\"ecl\":\"%d\"," \
			"\"cell_id\":\"%d\"}", \
			rssi_to_dbm(rsrp), pci, ecl, cell_id);
	if (NT26K_SendData("signal_report", dataToSend))
	{
		Debug_Printf("\r\nSignal info sent successfully\r\n");
		return 1;
	}else return 0;
}


/**
 * ATAT+QSCLK=1 命令使能睡眠功能
 * 再次发送任意AT指令能够唤醒
 */
uint8_t set_CAT1_enter_low_power(void)
{
	CAT1_MAIN_DTR_set(ON);
	if (sendCommand("AT+QSCLK=1\r\n", "OK", 10, 2))
	{
		CAT1_state_low_power = 1; //设置为已进入低功耗
		Debug_Printf("\r\nCAT1 enter low power mode suc\r\n");
		return 1; //成功
	}else
	{
		Debug_Printf("\r\nCAT1 enter low power mode err\r\n");
		return 0; //失败
	}
}





